package cn.kpt.auth.service.impl;

import cn.kpt.auth.service.TokenService;
import cn.kpt.beans.pojo.ItripUser;
import cn.kpt.beans.vo.userinfo.ItripUserTokenVO;
import cn.kpt.utils.EmptyUtils;
import cn.kpt.utils.MD5;
import cn.kpt.utils.RedisAPI;
import cn.kpt.utils.UserAgentUtil;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;

/**
 * @version 1.0
 * @ClassName TokenServiceImpl
 * @Description TODO
 * @Author kangpengtao
 * @Date 2019/9/28 17:34
 */
@Service
public class TokenServiceImpl implements TokenService {
    private final String TOKEN_PC = "PC-";
    private final String TOKEN_MOBILE = "MOBILE-";
    @Resource
    private RedisAPI redisAPI;

    @Override
    public String genToken(ItripUser itripUser, String userAgent) throws Exception {
        StringBuffer stringBuffer = new StringBuffer();
//        检测设备类别
        if (UserAgentUtil.CheckAgent(userAgent)) {
            if (UserAgentUtil.CheckAgent(userAgent)) {
                stringBuffer.append(TOKEN_MOBILE);
            } else {
                stringBuffer.append(TOKEN_PC);
            }
        }
        //加密USERCODE
        stringBuffer.append(MD5.getMd5(itripUser.getUserCode(), 16) + "-");
        //用户ID
        stringBuffer.append(itripUser.getId() + "-");
        //时间戳
        stringBuffer.append(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + "-");
        stringBuffer.append(MD5.getRandomCode());
        return stringBuffer.toString();
    }

    @Override
    public void saveToken(String token, ItripUser itripUser, String userAgent) throws Exception {
        //换掉以前的token信息
        Set<String> checkTokenKey = checkTokenKey(itripUser, userAgent);
        if (EmptyUtils.isNotEmpty(checkTokenKey)) {
            for (String key : checkTokenKey) {
                redisAPI.delete(key);
            }
        }
        saveTokenWithOutDel(token, itripUser, userAgent);
    }

    @Override
    public void delToken(String token) throws Exception {

        if (redisAPI.exist(TOKEN_KEY + token)) {
            redisAPI.delete(TOKEN_KEY + token);
        }
    }

    @Override
    public boolean checkTokenTimeOut(String token, String userAgent)throws Exception {
        //检查是否存在
        if (redisAPI.exist(TOKEN_TIME_OUT + token)) {
            //查看剩余时间
            Long ttl = redisAPI.ttl(TOKEN_TIME_OUT + token);
            //比较时间是否替换
            if (ttl <= TOKEN_REFRESH_TIME) {
                return true;
            }
        }
        return false;
    }

    @Override
    public String refreshToken(String token, String userAgent, ItripUser currentUser)throws Exception {
        if (!redisAPI.exist(TOKEN_KEY + token)) {
            throw new Exception("token已过期！");
        }
        //生成token信息
        String newtoken = genToken(currentUser, userAgent);
        //保存新token
        saveTokenWithOutDel(newtoken, currentUser, userAgent);
        //缓存旧token，
        redisAPI.set(TOKEN_KEY + token, TOKEN_CACHE_OLD_TIME, redisAPI.get(TOKEN_KEY+token));
        return newtoken;
    }

    //    获取之前的token信息
    public Set<String> checkTokenKey(ItripUser itripUser, String userAgent) {
        //账号唯一（换掉以前的信息）
        StringBuffer stringBuffer = new StringBuffer();
        //检测是PC还是移动
        if (UserAgentUtil.CheckAgent(userAgent)) {
            stringBuffer.append(TOKEN_MOBILE);
        } else {
            stringBuffer.append(TOKEN_PC);
        }
        //加密USERCODE
        stringBuffer.append(MD5.getMd5(itripUser.getUserCode(), 16) + "-");
        //用户ID
        stringBuffer.append(itripUser.getId() + "-");
        Set<String> keys = redisAPI.keys(TOKEN_KEY + stringBuffer.toString() + "*");
        return keys;
    }

    //保存token信息
    public void saveTokenWithOutDel(String token, ItripUser itripUser, String userAgent) {
        //存储用户信息
        ItripUserTokenVO itripUserTokenVO = new ItripUserTokenVO();
        BeanUtils.copyProperties(itripUser, itripUserTokenVO);
        String jsonString = JSON.toJSONString(itripUserTokenVO);
        //存储token:移动端永久，pc端一个小时
        if (UserAgentUtil.CheckAgent(userAgent)) {
            redisAPI.set(TOKEN_KEY + token, jsonString);
        } else {
            redisAPI.set(TOKEN_KEY + token, TOKEN_TIME_OUT, jsonString);
        }
    }
}
